package math;

import java.util.ArrayList;



public class WLeastSquareMethod {
	public Double estimate(ArrayList<Double> V, ArrayList<Double> U) {
		//estimate in V = b*U, b - argmin SUM[U^2(V-aU)^2] 
		ArrayList<Double> W = new ArrayList<Double>(); 
		for (int i=0; i<U.size(); i++) {
			W.add(Math.pow(U.get(i), 2.0));
		}
		Double sumUVW = 0.0;
		Double sumU2W = 0.0;
		for (int i=0; i<U.size(); i++) {
			Double u = U.get(i);
			sumUVW += u*V.get(i)*W.get(i);
			sumU2W += u*u*W.get(i);
		}
		return sumUVW/sumU2W;
			
	}
	public Double estimate(ArrayList<Double> V, ArrayList<Double> U, ArrayList<Double> W) {
		Double sumUVW = 0.0;
		Double sumU2W = 0.0;
		for (int i=0; i<U.size(); i++) {
			Double u = U.get(i);
			sumUVW += u*V.get(i)*W.get(i);
			sumU2W += u*u*W.get(i);
		}
		return sumUVW/sumU2W;
	}
	
	public Coeffs estimateFull (ArrayList<Double> V, ArrayList<Double> U) {
		ArrayList<Double> W = new ArrayList<Double>(); 
		for (int i=0; i<U.size(); i++) {
			W.add(Math.pow(U.get(i), 2.0));
		}
		int n = V.size();
		Double sumUV = 0.0;
		Double sumU = 0.0;
		Double sumV = 0.0;
		Double sumU2 = 0.0;
		for (int i=0; i<U.size(); i++) {
			Double u = U.get(i);
			Double v = V.get(i);
			Double w = W.get(i);
			sumUV += u*v*w;
			sumU2 += u*u*w;
			sumU  += u*w;
			sumV  += v*w;
		}
		Double b1 = (n*sumUV - sumU*sumV)/(n*sumU2 - sumU*sumU);
		return new Coeffs(sumV/n-b1*sumU/n, b1);
	}
	
	public Coeffs estimateFull (ArrayList<Double> V, ArrayList<Double> U, ArrayList<Double> W) {
		int n = V.size();
		Double sumUV = 0.0;
		Double sumU = 0.0;
		Double sumV = 0.0;
		Double sumU2 = 0.0;
		for (int i=0; i<U.size(); i++) {
			Double u = U.get(i);
			Double v = V.get(i);
			Double w = W.get(i);
			sumUV += u*v*w;
			sumU2 += u*u*w;
			sumU  += u*w;
			sumV  += v*w;
		}
		Double b1 = (n*sumUV - sumU*sumV)/(n*sumU2 - sumU*sumU);
		return new Coeffs(sumV/n-b1*sumU/n, b1);
	}
}
